﻿/***********************************
 * Developer: Lio.Huang
 * Create Date：2018-11-16
 * 
 * Last Update：
 * 2019-01-07  1. GetAdapter(connection)
 * 2019-01-21  1.增加同时多数据库支持
 * 2019-02-11  1.rename dbkey 
 **********************************/

using System;
using System.Collections.Concurrent;
using System.Data;
using housingsafety.server.Repository.Banana.Models;
using MySql.Data.MySqlClient;
using static housingsafety.server.Repository.Banana.Extension.SqlMapperExtensions;
using DbType = housingsafety.server.Repository.Banana.Models.DbType;

namespace housingsafety.server.Repository.Banana
{
    /// <summary>
    /// 创建基础链接| Creating database links
    /// </summary>
    public class ConnectionBuilder
    {
        private static ConcurrentDictionary<string, DbSetting> _dbSettingDic;
        /// <summary>
        /// Default key Name
        /// </summary>
        public const string DefaultAliase = "Banana-ORM";

        /// <summary>
        /// 注册链接|Register database links
        /// </summary>
        /// <param name="strConn">connection string</param>
        /// <param name="dBType">type of database</param>
        /// <param name="dbAliase">Multiple databases can be injected depending on the key</param>
        public static void ConfigRegist(string strConn, DbType dBType = DbType.SqlServer, string dbAliase = DefaultAliase)
        {
            var dbSetting = new DbSetting() { ConnectionString = strConn, DbType = dBType };
            ConfigRegist(dbSetting, dbAliase);
        }

        /// <summary>
        /// 注册链接|Register database links
        /// </summary>
        /// <param name="db">connection model</param>
        /// <param name="dbAliase">Multiple databases can be injected depending on the key</param>
        public static void ConfigRegist(DbSetting db, string dbAliase = DefaultAliase)
        {
            if (_dbSettingDic == null)
            {
                _dbSettingDic = new ConcurrentDictionary<string, DbSetting>();
            }
            if (string.IsNullOrEmpty(dbAliase))
            {
                dbAliase = DefaultAliase;
            }
            if (_dbSettingDic.ContainsKey(dbAliase))
            {
                throw new Exception("The same key already exists:" + dbAliase);
            }
            _dbSettingDic[dbAliase] = db;
        }

        /// <summary>
        /// 创建连接串|Create database connection
        /// </summary>
        public static IDbConnection CreateConnection(string dbAliase = DefaultAliase)
        {
            try
            {
                if (string.IsNullOrEmpty(dbAliase))
                {
                    dbAliase = DefaultAliase;
                }
                DbSetting dBSetting;
                if (!_dbSettingDic.TryGetValue(dbAliase, out dBSetting))
                {
                    throw new Exception("The key doesn't exist:" + dbAliase);
                }
                var conn = dBSetting.ConnectionString;
                switch (dBSetting.DbType)
                {
                    case DbType.SqlServer:
                    case DbType.SqlServer2012:
                        throw new Exception("Unregistered database link, please register by \"ConnectionBuilder.ConfigRegist\"");
                    case DbType.MySql:
                        return new MySqlConnection(conn);
                    case DbType.SqLite:
                    case DbType.Postgres:
                        return new Npgsql.NpgsqlConnection(conn);
                    case DbType.Oracle:
                        throw new Exception("Unregistered database link, please register by \"ConnectionBuilder.ConfigRegist\"");
                }

                throw new Exception("Unregistered database link, please register by \"ConnectionBuilder.ConfigRegist\"");
            }
            catch (Exception ex)
            {
                throw new Exception("Unregistered database link, please register by \"ConnectionBuilder.ConfigRegist\"");
            }
        }

        /// <summary>
        /// Get DB Option
        /// </summary>
        /// <param name="dbAliase">DB alias</param>
        /// <returns></returns>
        public static DbSetting GetDbSetting(string dbAliase = DefaultAliase)
        {
            if (string.IsNullOrEmpty(dbAliase))
                dbAliase = DefaultAliase;
            DbSetting dBSetting;
            if (!_dbSettingDic.TryGetValue(dbAliase, out dBSetting))
            {
                throw new Exception("The key doesn't exist:" + dbAliase);
            }
            return dBSetting;
        }
        /// <summary>
        /// The interface for all Dapper database operations 
        /// </summary>
        /// <returns></returns>
        internal static Interface.ISqlAdapter GetAdapter(IDbConnection connection)
        {
            return GetFormatter(connection);
        }
    }
}
